import { v3, size, Vec3, Size } from "cc";
import { GlobalEnum } from "../Config/GlobalEnum";
import { GlobalTmpData } from "../Config/GlobalTmpData";
import EventManager from "../Managers/EventManager";
import { EventTypes } from "../Managers/EventTypes";
import { AudioSystem } from "../SystemAudio/AudioSystem";
import SDK, { VideoState } from "./SDK";
import { GlobalConfig } from "../Config/GlobalConfig";
const tt = window['tt'];

export class TTSDK extends SDK {
    // tt8eb1f80c1180e8c702 : 天天补脑
    api = tt;

    protected onEvents() {
        super.onEvents();
        EventManager.on(EventTypes.GameEvents.GameRun, this.onGameRun, this);
        EventManager.on(EventTypes.GameEvents.GameOver, this.onGameOver, this);
        //
        EventManager.on(EventTypes.SDKEvents.StartRecord, this.onStartRecord, this);
        EventManager.on(EventTypes.SDKEvents.PauseRecord, this.onPauseRecord, this);
        EventManager.on(EventTypes.SDKEvents.ResumeRecord, this.onResumeRecord, this);
        EventManager.on(EventTypes.SDKEvents.StopRecord, this.onStopRecord, this);
        EventManager.on(EventTypes.SDKEvents.ShareRecord, this.onShareRecord, this);
        //
        EventManager.on(EventTypes.SDKEvents.CheckSiderbar, this.onCheckSiderbar, this);
        EventManager.on(EventTypes.SDKEvents.NavigateToScene, this.onNavigateToScene, this);
        EventManager.on(EventTypes.SDKEvents.GetOnShowMsg, this.onGetOnShowMsg, this);
        EventManager.on(EventTypes.SDKEvents.SetOnShowCallBack, this.onSetOnShowCallBack, this);

    }
    protected initSdk(callback?: Function, target?: any): void {
        this.api = tt;
        this.qingjs = tt['qingjs'];
        // 注册tt事件
        this.onShareAppMessage();
        this.onShow();
        // 初始化
        super.initSdk(callback, target);
        this._initVideo();
    }


    //#region --- 分享
    protected defaultTitle = '一起来玩吧!';

    protected curShareTitle = null;
    // 截图位置比例
    protected screenshotPos = v3(1, 1);
    // 截图大小比例 宽高比 5:4
    protected screenshotSize = size(1, 1);
    protected _canvas = null;

    // 分享截图路径 显示图片长宽比是 5:4
    private _getShareImageUrl() {
        const res = tt.getSystemInfoSync();
        const pixRate = res.pixelRatio; // 像素比
        const sw = res.windowWidth * pixRate;
        const sh = res.windowHeight * pixRate;

        if (!this._canvas) {
            // @ts-ignore
            this._canvas = tt.createCanvas();
            this._canvas.width = sw;
            this._canvas.height = sh;
        } else {
            let ctx = this._canvas.getContext('2d');
            ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
        }

        // 比例
        let xr = this.screenshotPos.x || 1;
        let yr = this.screenshotPos.y || 1;
        let wr = this.screenshotSize.width || 0.4;
        let hr = this.screenshotSize.height || 0.5;

        let w = wr * sw;
        let h = hr * sh;
        let x = xr * sw;
        let y = yr * sh;

        console.log('TT Share AreaSize: ', w, h, 'InfoSync size: ', sw, sh, 'pixRate: ', pixRate);
        // 同步方法
        try {
            let imageUrl = window['canvas'].toTempFilePathSync({
                x: x,
                y: y,
                width: w,
                height: h,
                destWidth: w,
                destHeight: h,
            })
            console.log('imageUrl', imageUrl);
            return imageUrl;
        } catch (error) {
            return null
        }
    }

    // 主动分享
    protected share(d: { title: string, pos: Vec3, size?: Size, success?, fail?}): void {
        if (d && d.title) {
            this.curShareTitle = d.title;
        }
        // 位置比例参数
        if (d && d.size) {
            this.screenshotSize.set(d.size);
        }
        // 大小比例参数
        if (d && d.pos) {
            this.screenshotPos.set(d.pos);
        }

        console.log("# 主动分享:", this.curShareTitle, this.screenshotPos, this.screenshotSize);

        let imageUrl = '';

        tt.shareAppMessage({
            title: this.curShareTitle || this.defaultTitle,
            imageUrl: imageUrl,
            success: () => {
                console.log("分享成功");
                if (d && d.success) {
                    d.success();
                }
                this.onShareComplete();
            },
            fail: () => {
                console.log("分享失败");
                if (d && d.fail) {
                    d.fail();
                }
            }
        })
    }
    // 被动分享-指定url
    onShare() {
        const self = this;
        this.curShareTitle = this.curShareTitle || this.defaultTitle;

        console.log("# 被动分享:", this.curShareTitle, this.screenshotPos, this.screenshotSize);

        const url = 'https://mmocgame.qpic.cn/wechatgame/2kzgVyoQgpADbnQpUQnxs2NvWWQsyKFzPdYxriblJQvIAcXLutibib0HibvmCibAxibicaa/0';
        tt.onShareAppMessage(function () {
            return {
                title: self.curShareTitle,
                imageUrl: url
            }
        })
    }

    //#endregion

    //#region -------------启动监听-侧边栏------
    // 监听启动信息:回到前台的事件回调
    private _onShowMsg = null;
    // onShow回调 只有进入游戏之后 从后台回到前台才会触发
    private _onShowCallBacks: Function[] = [];
    protected onShow() {
        tt.onShow((res) => {
            console.log("回到前台事件回调", res);
            // console.log("启动参数：", res.query);
            // console.log("来源信息：", res.refererInfo);
            // console.log("场景值：", res.scene);
            // console.log("启动场景字段：", res.launch_from, ", ", res.location);
            this._onShowMsg = res;
            // 回调事件
            this._onShowCallBacks.forEach(cb => {
                cb && cb(this._onShowMsg);
            });
        });
    }
    // 获取启动信息
    protected onGetOnShowMsg(cb) {
        cb && cb(this._onShowMsg);
    }
    // 设置回调
    protected onSetOnShowCallBack(cb: Function) {
        this._onShowCallBacks.push(cb);
    }


    //注册菜单分享事件
    protected onShareAppMessage() {
        tt.onShareAppMessage(() => {
            return {
                title: '这关好难啊!',
                // imageUrl: '',
                // title: '这是要转发的小程序标题',
                // desc: '这是默认的转发文案，用户可以直接发送，也可以在发布器内修改',
                // path: '/pages/index/index?from=sharebuttonabc&otherkey=othervalue', // ?后面的参数会在转发页面打开时传入onLoad方法
                // imageUrl: 'https://e.com/e.png', // 支持本地或远程图片，默认是小程序 icon
                // templateId: '这是开发者后台设置的分享素材模板id',
                // success() {
                //     console.log('转发发布器已调起，并不意味着用户转发成功，微头条不提供这个时机的回调');
                // },
                // fail() {
                //     console.log('转发发布器调起失败');
                // }
            }

        });
    }
    //添加桌面
    protected onAddShortcut(cb) {
        this.api && this.api.addShortcut({
            success() {
                this.isAddSuccess = true;
                console.log("添加桌面成功");
                EventManager.emit(EventTypes.GameEvents.ShowTips, '添加成功');
                cb && cb(true);
            },
            fail(err) {
                console.log("添加桌面失败", err.errMsg);
                cb && cb(false);
            },
        });
    }
    // 检测侧边栏是否可用
    protected onCheckSiderbar(cb) {
        if (tt) {
            tt.checkScene({
                scene: "sidebar",
                success: (res) => {
                    console.log("侧边栏可用");
                    // 跳转成功回调逻辑
                    cb && cb(true);
                },
                fail: (res) => {
                    console.log("侧边栏不可用", res);
                    // 跳转失败回调逻辑
                    cb && cb(false);
                }
            });

        } else {
            cb && cb(false);
        }
    }
    // 跳转侧边栏
    protected onNavigateToScene(cb) {
        if (tt) {
            tt.navigateToScene({
                scene: "sidebar",
                success: (res) => {
                    console.log("跳转成功");
                    // 跳转成功回调逻辑
                    cb && cb(true);
                },
                fail: (res) => {
                    console.log("跳转失败", res);
                    // 跳转失败回调逻辑
                    cb && cb(false);
                },
            });

        } else {
            cb && cb(false);
        }
    }

    //#endregion

    //#region -------------插屏广告
    insertId = 'xx';
    insertAd: any;
    isInsertShowed = false;

    protected showInterstitial() {
        console.log('TT 关闭插屏');
        return;

        if (this.isInsertShowed) {
            this.isInsertShowed = false;
            if (this.insertAd) {
                this.insertAd.offClose();
                this.insertAd.destroy();
                this.insertAd = null;
            }
        }

        this.insertAd = this.api.createInterstitialAd({
            adUnitId: this.insertId
        })
        this.insertAd.load().then(() => {
            console.log("插屏加载成功");

            this.insertAd && this.insertAd.show()
                .then((res) => {
                    this.isInsertShowed = true;
                    console.log("展示插屏成功");

                }).catch((err) => {
                    this.isInsertShowed = true;
                    console.log("展示插屏失败", err)
                    if (this.insertAd) {
                        this.insertAd.offClose();
                        this.insertAd.destroy();
                    }
                    this.insertAd = null;
                });
        })

    }


    //#endregion

    //#region -------------视频广告--
    videoAdList = {
        [GlobalEnum.VideoIdx.LvPass]: { id: '8dcc5e051ie7r4xors', ui: '通关奖励', ad: null, state: VideoState.unLoad },
        [GlobalEnum.VideoIdx.RecoverHP]: { id: '1jsuh9os05s61f5bsk', ui: '恢复血量', ad: null, state: VideoState.unLoad },
        [GlobalEnum.VideoIdx.Prop3]: { id: '1m2le21e3084esc2ch', ui: '道具-潜艇', ad: null, state: VideoState.unLoad },
        [GlobalEnum.VideoIdx.Prop2]: { id: '1jnj1jf0fmg35fc61t', ui: '道具-炮竹', ad: null, state: VideoState.unLoad },
        [GlobalEnum.VideoIdx.Prop1]: { id: '25wpcbmijt157c9idr', ui: '道具-铲子', ad: null, state: VideoState.unLoad },
        [GlobalEnum.VideoIdx.AddEnergy]: { id: '2ieuu5hd5ql2908vp4', ui: '体力不足', ad: null, state: VideoState.unLoad },
        [GlobalEnum.VideoIdx.AddGold]: { id: '127ll3oo9a8dggn42o', ui: '金币不足', ad: null, state: VideoState.unLoad },
        [GlobalEnum.VideoIdx.GetGift]: { id: '456dg5mbiadk29lkb7', ui: '新手大礼包', ad: null, state: VideoState.unLoad },
        [GlobalEnum.VideoIdx.Turntable]: { id: '6h9o7p93hjgiio8aj6', ui: '转盘', ad: null, state: VideoState.unLoad },
        [GlobalEnum.VideoIdx.MissionGift]: { id: '369flo74j5dmj90544', ui: '任务礼包', ad: null, state: VideoState.unLoad },

    };


    private _videoSuccessCb = null;
    private _videoFailCb = null;

    protected _initVideo() {
    }
    // 加载指定广告 并记录状态
    protected async _loadVideo(videoIdx: GlobalEnum.VideoIdx) {
        const rec = this.videoAdList[videoIdx];

        if (!rec.ad) {
            rec.state = VideoState.unLoad;
            rec.ad = tt.createRewardedVideoAd({ adUnitId: rec.id, multiton: true });

            // 加载成功
            rec.ad.onLoad(() => {
                rec.state = VideoState.success;
                console.log('激励视频 广告加载成功 ID: ' + rec.id);
            })
            // 加载失败
            rec.ad.onError(err => {
                console.log('激励视频 加载失败 ID:', rec.id, err);
                this.showMessage('暂时没有视频广告');
                rec.state = VideoState.unLoad;
            })

            // 用户点击了【关闭广告】按钮
            rec.ad.onClose(res => {
                // 小于 2.1.0 的基础库版本，res 是一个 undefined
                if (res && res.isEnded || res === undefined) {
                    // 正常播放结束，可以下发游戏奖励
                    if (this._videoSuccessCb) {
                        this._videoSuccessCb();
                    }
                    //播放完成LOG
                    this.onCompleteAd(rec.ui, 'video');
                    this.onVideoComplete();
                    console.log('激励视频 播放完成 ID: ' + rec.id);
                } else {
                    // 播放中途退出，不下发游戏奖励
                    if (this._videoFailCb) {
                        this._videoFailCb();
                    }
                    this.showMessage('播放完成才有游戏奖励哦');
                    console.log('激励视频 播放中途退出');
                }

                console.log('激励视频 广告关闭,准备预加载下一个');
                rec.state = VideoState.loading;
                rec.ad.load();
                
                // 恢复游戏+音乐
                EventManager.emit(EventTypes.GameEvents.GameResume);
                AudioSystem.resumeBGM();
            });
        }
        if (rec.state == VideoState.unLoad ||
            rec.state == VideoState.fail) {
            rec.state = VideoState.loading;
            await rec.ad.load();
            console.log('激励视频 广告开始加载 ID: ', rec.id);
        }
    }
    // 清除广告事件 + 状态
    protected clearVideoAd(idx) {
        if (this.videoAdList[idx]) {
            // 清除广告
            console.log('清除激励视频广告,ID:', this.videoAdList[idx].id);

            const ad = this.videoAdList[idx].ad;
            if (ad) {
                ad.offError();
                ad.offClose();
                ad.offLoad();
            }
            this.videoAdList[idx].state = VideoState.unLoad;
        }
    }
    /**
      * 拉起激励视频广告
      */
    protected async showRewardedVideo(cb: Function | { success: Function, fail: Function }, videoIdx = GlobalEnum.VideoIdx.LvPass) {
        const rec = this.videoAdList[videoIdx];
        if (!rec) {
            console.warn('没有视频广告配置 videoIdx : ' + videoIdx);
            return;
        }

        console.log('# 视频广告ID: ', rec.id, this.videoAdList[videoIdx].ui);

        // 显示触摸屏蔽
        this.showVideoTouchMask();

        // 判断状态
        let msg = null;
        if (rec.ad && rec.state == VideoState.loading) {
            msg = '激励视频 广告正在加载中,请稍后...';
            console.warn(msg);
            this.showMessage(msg);
            return;
        }

        // 重新加载
        if (!rec.ad || rec.state != VideoState.success) {
            this.showMessage('视频广告正在加载中,请稍后...');
            await this._loadVideo(videoIdx);
        }

        // 记录回调参数
        if (typeof cb === 'object') {
            this._videoSuccessCb = cb.success;
            this._videoFailCb = cb.fail;
        } else {
            this._videoSuccessCb = cb;
        }

        // 测试 直接返回成功
        if (GlobalConfig.isCloseVideo) {
            rec.state = VideoState.success;
            setTimeout(() => {
                this._videoSuccessCb && this._videoSuccessCb();
                this.onVideoComplete();
                // 恢复游戏+音乐
                EventManager.emit(EventTypes.GameEvents.GameResume);
                AudioSystem.resumeBGM();
            }, 0);
            return;
        }

        // 播放
        if (rec.ad) {
            //暂停游戏
            EventManager.emit(EventTypes.GameEvents.GamePause);
            AudioSystem.pauseBGM();
            console.log('激励视频 准备播放 ID: ', rec.id, rec.ad);

            // 播放
            rec.ad.show().then(() => {
                console.log('激励视频 广告显示成功');
                //播放LOG
                this.onShowAd(rec.ui, 'video');
            });
            // 点击LOG
            this.onClickAd(rec.ui, 'video');
        }
    }


    //#endregion

    //#region -------------硬件功能
    // 震动：heavy、medium、light
    // 短震动
    protected onShortVibration() {
        if (!tt || !GlobalTmpData.Setting.Audio.vibration) return;
        tt.vibrateShort({
            type: 'heavy',
        })
    }
    // 长震动
    protected onLongVibration() {
        if (!tt || !GlobalTmpData.Setting.Audio.vibration) return;
        tt.vibrateLong({
        })
    }
    //#endregion

    //#region --------事件---------
    protected onGameRun() {
    }

    protected onGameOver() {
    }

    //--录屏
    protected onStartRecord() {
        ScreenRecorder.inst.start();
        console.log("录屏开始");
    }
    protected onPauseRecord() {
        console.log("录屏暂停");
    }
    protected onResumeRecord() {
        console.log("录屏恢复");
    }
    //停止录屏（头条）
    protected onStopRecord() {
        ScreenRecorder.inst.stop();
        console.log("录屏结束");
    }
    //分享录屏（头条）
    protected onShareRecord(success?: Function, fail: Function = null) {
        console.log("分享录屏");
        ScreenRecorder.inst.share(success, fail);
    }


    //#endregion


    //#region --- 上报日志

    // 进入关卡
    onEnterStage() {
        if (!GlobalTmpData.Game.isGuideLv) {
            this.onStartRecord();
        }

        let msg = this._getCurLvMsg();
        let data = {
            stage: msg,
            new_user: this.isNewUser + '',
            esay_type: GlobalTmpData.LvLogoData.easyType,
            enter_count: GlobalTmpData.LvLogoData.enterCount,
        }
        if (GlobalTmpData.Game.isGuideLv) {
            data.enter_count = 1;
            data.esay_type = '简单';
        }

        // tt
        this.onReportEvent(GlobalEnum.ReportName.EnterStage, data);
        // cx
        this.qingjs.instance.eventReporter.enterStage(data);
    }

    exitStates = ['胜利', '失败', '中途退出'];
    // 退出关卡
    onExitStage(state: GlobalEnum.ExitLvState) {

        if (!GlobalTmpData.Game.isGuideLv) {
            this.onStopRecord();
        }

        // tt上报
        let msg = this._getCurLvMsg() + ' ' + this.exitStates[state];

        let data = {
            stage: msg,
            new_user: this.isNewUser + '',
            esay_type: GlobalTmpData.LvLogoData.easyType,
            enter_count: GlobalTmpData.LvLogoData.enterCount,
            fail_count: GlobalTmpData.LvLogoData.failCount,
            //
            tip_count: GlobalTmpData.LvLogoData.tipCount,
            stage_time: Math.floor(GlobalTmpData.Game.gameTime),
            is_pass: (state == 0 ? 'true' : 'false'),
        };
        // tt
        this.onReportEvent(GlobalEnum.ReportName.ExitStage, data);
        // cx
        this.qingjs.instance.eventReporter.exitStage(data);
    }

    // 显示广告按钮
    onShowAdButton(idx: GlobalEnum.VideoIdx, adType: string) {
        let ui = this.videoAdList[idx].ui;
        let data = {
            ad_type: adType,
            opportunity: ui,
            new_user: this.isNewUser + '',
        }

        // tt上报
        this.onReportEvent(GlobalEnum.ReportName.ShowAdButton, data);
        // cx
        this.qingjs.instance.eventReporter.showAdButton(data);
    }
    // 点击广告
    onClickAd(ui: string, adType: string) {
        let data = {
            ad_type: adType,
            opportunity: ui,
            new_user: this.isNewUser + '',
        }
        // tt上报
        this.onReportEvent(GlobalEnum.ReportName.ClickAdButton, data);
        // cx
        this.qingjs.instance.eventReporter.clickAd(data);
    }
    // 展示广告
    onShowAd(ui: string, adType: string) {
        let data = {
            ad_type: adType,
            opportunity: ui,
            new_user: this.isNewUser + '',
        }
        // tt上报
        this.onReportEvent(GlobalEnum.ReportName.ShowAd, data);
        // cx
        this.qingjs.instance.eventReporter.showAd(data);
    }
    // 完整观看广告
    onCompleteAd(ui: string, adType: string) {
        let data = {
            ad_type: adType,
            opportunity: ui,
            new_user: this.isNewUser + '',
        }
        // tt上报
        this.onReportEvent(GlobalEnum.ReportName.SuccessWatchAd, data);
        // cx
        this.qingjs.instance.eventReporter.completeAd(data);
    }

    //#endregion


}

export class ScreenRecorder {

    private recorder;   // 录屏实例
    private videoPath: string;   //  视频地址
    private actionRecord: any;   //  settimeout
    private recordingSecond: number;   //  录制时间
    private isRecording: Boolean;   // 是否在录制


    constructor() {
        if (typeof tt === 'undefined') return;
        if (!this.recorder) this.recorder = tt.getGameRecorderManager();
    }

    private static _inst: ScreenRecorder;

    static get inst() {
        if (!this._inst) {
            this._inst = new ScreenRecorder();
        };
        return this._inst;
    }
    static set inst(v) { };

    public start(): void {
        if (typeof tt === 'undefined') return

        this.recorder.start({
            duration: 300
        })
        this.isRecording = true;
        this.recordingSecond = 0;
        //开启一个计时器，统计录制了几秒钟，如果大于300则停止录制
        this.actionRecord = setInterval(() => {
            this.recordingSecond++
            if (this.recordingSecond >= 300) {
                this.isRecording = false
                clearInterval(this.actionRecord);
                this.recorder.stop()
            }
        }, 1000);

        this.recorder.onStop((res) => {
            this.isRecording = false
            clearInterval(this.actionRecord);
            this.videoPath = res.videoPath;
        });
    }

    public stop(): void {
        if (typeof tt === 'undefined') return
        if (!this.isRecording) return
        this.recorder.stop()
    }

    public share(success, fail): void {
        if (typeof tt === 'undefined') return

        let that = this;
        console.log(this.videoPath);
        if (!this.videoPath) {
            EventManager.emit(EventTypes.GameEvents.ShowTips, '分享失败');
            // success('fail', '分享失败')
            return
        }
        if (this.recordingSecond < 4) { //录制时间不能小于三秒
            that.videoPath = ''
            EventManager.emit(EventTypes.GameEvents.ShowTips, '录制时间过短');
            // fail('fail', '录制时间过短')
            return
        }


        tt.shareAppMessage({
            channel: "video",
            extra: {
                videoPath: this.videoPath, // 可用录屏得到的视频地址
                withVideoId: true,
                hashtag_list: ['消消乐', '抖音小游戏', '数独'],
                videoTopics: ['抖音小游戏'],
                video_title: '这个游戏真解压！'
            },
            success() {
                console.log("分享成功");
                //分享成功
                success && success();
                // that.videoPath = '';
                EventManager.emit(EventTypes.GameEvents.ShowTips, '分享成功');
            },
            fail(e) {
                console.log("分享失败", e);
                fail && fail();
                // that.videoPath = '';
                // callBack('fail', '分享失败')
                EventManager.emit(EventTypes.GameEvents.ShowTips, '分享失败');
            },
        });
    }

    public clear() {
        if (typeof tt === 'undefined') return
        if (!this.isRecording) return
        this.recorder.stop();
        this.videoPath = '';
    }
}